package bot {

import com.google.appengine.api.xmpp.JID;
import com.google.appengine.api.xmpp.Message;
import com.google.appengine.api.xmpp.MessageBuilder;
import com.google.appengine.api.xmpp.SendResponse;
import com.google.appengine.api.xmpp.XMPPService;
import com.google.appengine.api.xmpp.XMPPServiceFactory;
import java.util.logging.Logger;

import scala.collection._

object ConnectionHandler {
	var doLog: Boolean = true
 
	def processPublicMessage(message: Message) = {
		val fromJid: JID = message.getFromJid();
		val nick: String = UserManager.getNick(ChatUser.jid2email(fromJid));
		val users: Seq[ChatUser] = scala.collection.JavaConversions.asBuffer(UserManager.getOnlineUsers())
		logInfo("public message from " + fromJid.toString() + ": '" + message.getBody() + "'")
		for (user <- users) {
			val toJid: JID = user.getJid();
			// don't send if to and from are identical
			if (!ChatUser.jid2email(toJid).equals(ChatUser.jid2email(fromJid))) {
				sendMessage(toJid, "*" + nick + "*: " + message.getBody());
			}
		}
	}
	
	def processStatusMessage(msg: String) = {
		val users: Seq[ChatUser] = scala.collection.JavaConversions.asBuffer(UserManager.getOnlineUsers())
		for (user <- users) {
			val toJid: JID = user.getJid();
			sendMessage(toJid, msg);
		}
	}
	
 	def processPrivateMessage(nick: String, message: Message, msg: String) = {
		val toJid: JID = UserManager.getUser(nick).getJid()
		val fromNick = UserManager.getNick(message.getFromJid().toString())
 	  
		logInfo("private message from " + message.getFromJid().toString() + "to " + toJid.toString() + ": '" + message + "'")
		sendMessage(toJid, "_**" + fromNick + "**_: " + msg);
 	}

  	def sendMessage(toJid: JID, msg: String, sendAlways: Boolean = false) : Boolean = {
        var xmpp: XMPPService = XMPPServiceFactory.getXMPPService()

        if (!sendAlways && !(UserManager.isOnline(toJid))) {
        	return false;
        }
        var messageSent: Boolean = false;
        logInfo("message to " + toJid + ": " + msg);
        var echo: Message = new MessageBuilder()
            .withRecipientJids(toJid)
            .withBody(msg)
            .build()
        try {
		    if (xmpp.getPresence(toJid).isAvailable()) {
		        var status: SendResponse = xmpp.sendMessage(echo);
		        messageSent = (status.getStatusMap().get(toJid) == SendResponse.Status.SUCCESS);
		        if (messageSent) {
		        	logInfo("message sent to: " + toJid.toString());
		        }
		    }
		    else {
		    	// not available, set offline
		    	UserManager.setOnline(toJid, false, "disconnected");
		    	logWarn("user not available: " + toJid.toString());
		    }
        } catch {
          	case e: Exception => {
          		logWarn("Exception when probing user availability: " + e)
		    	UserManager.setOnline(toJid, false, "disconnected/no status available");
          	}
        }
        
        return messageSent;
	}
	
	/* public static void sendInvitation(JID toJid) {
        XMPPService xmpp = XMPPServiceFactory.getXMPPService();
        xmpp.sendInvitation(toJid);
    } */
 
    def setLogging(set: Boolean) {
    	doLog = set
    }
    
    def logInfo(msg: String) = {
    	if (doLog) {
    		var log: Logger = Logger.getLogger("bot.BotServlet")
    		log.info(msg)
    	}
    }

    def logWarn(msg: String) = {
    	if (doLog) {
    		var log: Logger = Logger.getLogger("bot.BotServlet")
    		log.warning(msg)
    	}
    }

}

} // package bot
